import React, { useEffect, useState, useRef } from "react";
import { Outlet, useNavigate } from "react-router-dom";
import { Layout, Menu, Image, message } from "antd";
import type { MenuProps } from "antd";
import { setUserInfo, setPermissions, setTitle } from "@/stores/actions";
import WhaleHeader from "@/component/Header";
import Icon from "@/component/common/Icon"
import { useSize } from "ahooks";
import PubSub from "pubsub-js";
import logo from "@/assets/whale.png";
import { $get } from "@/api/RestUtils";
import TreeUtils from "@/utils/TreeUtils"
import { useDispatch } from "react-redux";
import "./index.less";

const { Header, Content, Footer, Sider } = Layout;

type MenuItem = Required<MenuProps>["items"][number];
function getItem(
  key: React.Key,
  label: React.ReactNode,
  icon?: React.ReactNode,
  children?: MenuItem[],
  type?: "group"
): MenuItem {
  return {
    key,
    icon,
    children,
    label,
    type,
  } as MenuItem;
}

const App: React.FC = () => {
  const [menuKey, setMenuKey] = useState<string>("");
  const [collapsed, setCollapsed] = useState(false);
  const [titleShow, setTitleShow] = useState(true);
  const [menuList, setMenuList] = useState<MenuItem[]>();
  const [menuRouteMap, setMenuRouteMap] = useState<Map<string, any>>(new Map());

  const ref = useRef(null);

  const siderSize = useSize(ref);

  const navigate = useNavigate();
  const dispatch = useDispatch();

  useEffect(() => {
    let source = menuRouteMap.get(menuKey)
    if (source) {
      let path = source["sourceRoute"]
      let title = source["sourceName"]
      dispatch(setTitle(title));
      navigate(path);
    }
  }, [menuKey]);

  useEffect(() => {
    PubSub.subscribe("userInfoChange", (topic: string, msg: boolean) => {
      if (msg) {
        getUserInfo();
      }
    });
    return () => {
      PubSub.unsubscribe("userInfoChange");
    };
  }, []);

  useEffect(() => {
    if (siderSize?.width === 200) {
      setTitleShow(true);
    } else {
      setTitleShow(false);
    }
  }, [siderSize]);

  useEffect(() => {
    getUserInfo();
    getSourceCodes();
    getSourceList();
  }, []);

  const toggleCollapsed = (collapsed: boolean) => {
    setCollapsed(collapsed);
  };

  const menuChange: MenuProps["onClick"] = (item) => {
    setMenuKey(item.key);
  };

  const getUserInfo = () => {
    $get("/user/info", null)
      .then((res: any) => {
        if (res.code === 0) {
          dispatch(setUserInfo(res.data))
        } else {
          message.error(res.msg);
        }
      })
      .catch((err: any) => {
        message.error("系统异常");
      });
  };

  const getSourceCodes = () => {
    $get("/source/getPermissionList", null)
      .then((res: any) => {
        if (res.code === 0) {
          dispatch(setPermissions(res.data))
        } else {
          message.error(res.msg);
        }
      })
      .catch((err: any) => {
        message.error("系统异常");
      });
  };

  const getSourceList = () => {
    $get("/source/getSourceList", null)
      .then((res: any) => {
        if (res.code === 0) {
          loadMenuList(res.data);
          let map: Map<string, any> = new Map()
          res.data.forEach((item: any) => {
            map.set(String(item.sourceId), item)
            if (item.sourceCode == "index") {
              setMenuKey(String(item.sourceId))
            }
          })
          setMenuRouteMap(map);
        } else {
          message.error(res.msg);
        }
      })
      .catch((err: any) => {
        message.error("系统异常");
      });
  };

  const loadMenuList = (sourceList: any[]) => {
    let list: any[] = list2TreeForNav(sourceList)
    setMenuList(list);
  };

  const list2TreeForNav = (list: any[]): any[] => {
    let dealtList: any = list.map((item: any) => {
      return {
        id: item.sourceId,
        key: item.sourceCode,
        label: item.sourceName,
        icon: <Icon icon={item.icon} />,
        parentId: item.parentId
      }
    })
    let field = {id: "id", parentId: "parentId"}
    return TreeUtils.list2Tree(dealtList, field, true);
  };

  const renderTitle = () => {
    if (titleShow) {
      return <div className="label">Whale-Admin</div>;
    } else {
      return <></>;
    }
  };

  return (
    <Layout>
      <Sider
        ref={ref}
        collapsible
        collapsed={collapsed}
        onCollapse={toggleCollapsed}
      >
        <div className="title">
          <div className="logo">
            <Image src={logo} preview={false}></Image>
          </div>
          {renderTitle()}
        </div>
        <Menu
          theme="dark"
          mode="inline"
          selectedKeys={[menuKey]}
          onClick={menuChange}
          items={menuList}
        />
      </Sider>
      <Layout className="layout-right">
        <Header>
          <WhaleHeader />
        </Header>
        <Content>
          <Outlet />
        </Content>
        <Footer>Copyright (c) 2023 voracious</Footer>
      </Layout>
    </Layout>
  );
};

export default App;
